﻿#include "Thread.h"
#include "IRunable.h"
#include "ThreadManager.h"

namespace sky
{
    // 线程封装

    Thread::Thread(): mThreadId(0), mThreadHandle(0), m_pTask(NULL)
    {
		//添加到列表 TODO
		ThreadManager::getInstance().addThread(this);
    }

    Thread::~Thread()
    {
        terminate();
        // 从列表中删除
		ThreadManager::getInstance().removeThread(this);

    }

    bool Thread::spawn(ThreadRunnable *task, int priority)
    {
        m_pTask = task;
        m_pTask->setThread(this);
        m_pTask->setRun(true);

        mThreadHandle = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)&_dispatch, task, CREATE_SUSPENDED,(DWORD*)&mThreadId);
        ::SetThreadPriority(mThreadHandle, priority);
        ::ResumeThread(mThreadHandle);

        return mThreadHandle != NULL;
    }

    void Thread::clearTask()
    {
        if (m_pTask)
        {
            m_pTask->notifyStop();
            m_pTask->setThread(NULL);
            m_pTask = NULL;
        }
    }

    void Thread::wait()
    {
        if (mThreadHandle == NULL)
        {
            return;
        }

        ::WaitForSingleObject(mThreadHandle, INFINITE);

        mThreadHandle = NULL;
    }

    void Thread::start()
    {
        ::ResumeThread(mThreadHandle);
    }

    void Thread::pause()
    {
        ::SuspendThread(mThreadHandle);
    }

    void Thread::terminate()
    {
        if (mThreadHandle)
        {
            clearTask();
            //这里唤醒一下线程
            start();
            //没有等到进程结束,强行杀进程
            if (WAIT_OBJECT_0 != ::WaitForSingleObject(mThreadHandle, WAIT_TERMINATE_TIME))
            {
                ::SuspendThread(mThreadHandle);
                ::TerminateThread(mThreadHandle, 0);

                // InfoLn("强杀线程,存在隐患" << GetLastError() ); 
            }

            ::CloseHandle(mThreadHandle);
            mThreadHandle = NULL;

        }
    }

    void Thread::sleep(unsigned long timeout)
    {
        Sleep(timeout);
    }

    void Thread::notifyStop()
    {
        if(m_pTask)
        {
            m_pTask->notifyStop();
            m_pTask->setThread(NULL);
            m_pTask = NULL;
        }
    }

    //查询线程是否已经停止运行
    bool Thread::isClose()
    {
        if (mThreadHandle)
        {
            //看线程的内核对象是否在通知状态
            return (WAIT_OBJECT_0 == ::WaitForSingleObject(mThreadHandle, 0));
        }

        return true;
    }

    unsigned int __stdcall Thread::_dispatch(void *arg)
    {
        ThreadRunnable * task = reinterpret_cast<ThreadRunnable*>(arg);
        // Assert(task);
        if (false == task->isRun())
        {
            return 0;
        }
        
        try
        {
            task->run();
        }
        catch(...)
        {
            // Warning("Thread("<<::GetCurrentThreadId()<<") catch error"<<endl);
        }
        
        return 0;
    }

} // namespace sky
